﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Terminal.Advanced_AEUC_settings_controls.Settings_AUX;
using Terminal.Advanced_AEUC_settings_controls.Settings_Interfaces;
using Terminal.Advanced_AEUC_settings_controls.Settings_Editing_Forms;
using Terminal.Advanced_AEUC_settings_controls.Setting_Advanced_Control;
using Terminal.Advanced_AEUC_settings_controls.Scripting;
using CommLink;
using Auxiliaries;
using System.IO;

namespace Terminal.Advanced_AEUC_settings_controls.Scripting
{
    /// <summary>
    /// Scripting module UI main view
    /// </summary>
    public partial class ScriptingModule : Form
    {
        public class OMXComponent
        {
            /// <summary>
            /// Name of the OMX Component
            /// </summary>
            public string omxName;
            /// <summary>
            /// OMX Component IAUECSettings
            /// </summary>
            public GenTabPageProperties[] gtpProperties;
            /// <summary>
            /// OMX Component messaging
            /// </summary>
            public GenMSG[] messages;
        }
        /// <summary>
        /// Payload struct representing tree node, with context menu for spawning payload struct editting form
        /// </summary>
        internal class GenPldStructTNode : TreeNode
        {
            #region Context menu item declaration
            const string CTX_MENU_ADD_CMD_LINE = "Add to command line";
            const string CTX_MENU_OPN_STRUCT_EDIT = "Open struct edit form";
            #endregion

            /// <summary>
            /// Reference to the payload struct associated to this tree node
            /// </summary>
            public GenPayloadStruct pldStruct;
            /// <summary>
            /// Reference to the rich-text edit box for the scripting command line
            /// </summary>
            RichTextBox rtScrCmdLine;

            /// <summary>
            /// Public constructor
            /// </summary>
            /// <param name="iPldStruct">Payload struct to associate to this tree node</param>
            /// <param name="iRtScrCmdLine">Rich text editing box for the scipt command line</param>
            public GenPldStructTNode(GenPayloadStruct iPldStruct, RichTextBox iRtScrCmdLine)
                : base(iPldStruct.dispName)
            {
                pldStruct = iPldStruct;
                rtScrCmdLine = iRtScrCmdLine;

                #region Context menu initialization
                ContextMenuStrip = new ContextMenuStrip();
                EventHandler eh = new EventHandler(ContextMenuHandler);
                ContextMenuStrip.Items.Add(CTX_MENU_ADD_CMD_LINE, null, eh);
                ContextMenuStrip.Items.Add(CTX_MENU_OPN_STRUCT_EDIT, null, eh);
                #endregion
            }

            /// <summary>
            /// Handler for the payload struct tree node contex menu
            /// </summary>
            /// <param name="sender">Menu item that trigered the event</param>
            /// <param name="ea">event arguments</param>
            private void ContextMenuHandler(object sender, EventArgs ea)
            {
                ToolStripItem tmpItem = (ToolStripItem)sender;

                if (tmpItem.Text == CTX_MENU_ADD_CMD_LINE)
                {
                    rtScrCmdLine.AppendText(pldStruct.dispName + " ");
                }
                else if (tmpItem.Text == CTX_MENU_OPN_STRUCT_EDIT)
                {
                    GenPldStructEditForm genEdit = new GenPldStructEditForm(pldStruct);
                    genEdit.ShowDialog();
                }
            }
        }
        /// <summary>
        /// Payload struct editing form - auxiliary UI for editing structure contents
        /// </summary>
        internal class GenPldStructEditForm : Form
        {
            /// <summary>
            /// Associated payload struct - apply changes will go here
            /// </summary>
            GenPayloadStruct pldStruct;

            #region UI elements
            Button apply = new Button();
            Button cancel = new Button();
            CheckBox toHex = new CheckBox();
            Panel pldsItems = new Panel();
            #endregion

            /// <summary>
            /// Public constructor
            /// </summary>
            /// <param name="iPldStruct">Payload struct to associate the edit form with</param>
            public GenPldStructEditForm(GenPayloadStruct iPldStruct)
            {
                pldStruct = iPldStruct;

                FormBorderStyle = FormBorderStyle.SizableToolWindow;
                Text = pldStruct.dispName;
                Size = new Size(300, 450);

                int UIoffsetX = 10;
                int UIoffsetY = 15;

                apply = new Button();
                Controls.Add(apply);
                apply.Location = new Point(UIoffsetX, UIoffsetY);
                apply.Text = "Apply";
                apply.Click += new EventHandler(apply_Click);
                AcceptButton = apply;

                cancel = new Button();
                Controls.Add(cancel);
                cancel.Location = new Point(apply.Location.X + apply.Size.Width + UIoffsetX, apply.Location.Y);
                cancel.Text = "Cancel";
                CancelButton = cancel;

                toHex = new CheckBox();
                Controls.Add(toHex);
                toHex.Location = new Point(cancel.Location.X + cancel.Size.Width + UIoffsetX, cancel.Location.Y);
                toHex.Text = "Hex";
                toHex.CheckStateChanged += new EventHandler(toHex_CheckStateChanged);

                pldsItems = new Panel();
                Controls.Add(pldsItems);
                pldsItems.Location = new Point(apply.Location.X, apply.Location.Y + apply.Size.Height + UIoffsetY);
                pldsItems.AutoScroll = true;
                pldsItems.Size = new Size(Size.Width - 2 * pldsItems.Location.X, Size.Height - 2 * pldsItems.Location.Y);
                pldsItems.Anchor = AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right | AnchorStyles.Top;

                Graphics gfx = CreateGraphics();
                SizeF tmpStringMeasure;
                int ColumnOffset = 0;

                for (int i = 0; i < pldStruct.structContentsStringRep.Length; i++)
                {
                    tmpStringMeasure = gfx.MeasureString(pldStruct.structContentsStringRep[i].dispName, Font);
                    if (ColumnOffset < tmpStringMeasure.Width)
                        ColumnOffset = (int)tmpStringMeasure.Width;
                }

                Label tmpLblMsr = new Label();
                if (ColumnOffset < tmpLblMsr.Width)
                    ColumnOffset = tmpLblMsr.Width;

                Point colmn1 = new Point(10, 10);
                Point colmn2 = new Point(colmn1.X + ColumnOffset + UIoffsetX, colmn1.Y);

                for (int i = 0; i < pldStruct.structContentsStringRep.Length; i++)
                {
                    Label tmpLbl = new Label();
                    tmpLbl.Size = new Size(ColumnOffset, tmpLbl.Height);
                    pldsItems.Controls.Add(tmpLbl);
                    tmpLbl.Location = colmn1;
                    colmn1.Y += 30;
                    tmpLbl.Text = pldStruct.structContentsStringRep[i].dispName;

                    TextBox tmpTxb = new TextBox();
                    pldsItems.Controls.Add(tmpTxb);
                    tmpTxb.Location = colmn2;
                    colmn2.Y = colmn1.Y;
                    if (pldStruct[pldStruct[tmpLbl.Text]].GetType() == typeof(Byte[]))
                    {
                        tmpTxb.Text = "";
                        Byte[] tmpBtF = (Byte[])pldStruct[pldStruct[tmpLbl.Text]];
                        for (int ikc = 0; ikc < tmpBtF.Length - 1; ikc++)
                            tmpTxb.Text += tmpBtF[ikc].ToString() + ",";
                        tmpTxb.Text += tmpBtF[tmpBtF.Length - 1].ToString();
                    }
                    else
                        tmpTxb.Text = pldStruct[pldStruct[tmpLbl.Text]].ToString();
                }
            }
            /// <summary>
            /// Set the edit form values to the associated payload struct
            /// </summary>
            void updateValues()
            {
                for (int i = 0; i < pldsItems.Controls.Count; i += 2)
                {
                    if (pldsItems.Controls[i + 1].Text.Contains(','))
                    {
                        string[] arrItmsStr = pldsItems.Controls[i + 1].Text.Split(',');
                        Byte[] arrItms = new Byte[arrItmsStr.Length];

                        for (int ikc = 0; ikc < arrItmsStr.Length; ikc++)
                        {
                            arrItms[ikc] = (Byte)Calculator.ParseInteger(arrItmsStr[ikc]);
                        }

                        pldStruct[pldStruct[pldsItems.Controls[i].Text]] = arrItms;
                    }
                    else
                        pldStruct[pldStruct[pldsItems.Controls[i].Text]] = Calculator.ParseInteger(pldsItems.Controls[i + 1].Text);
                }
            }
            /// <summary>
            /// When the hex view check box check state is changed, update the text boxes to match the desired view.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            void toHex_CheckStateChanged(object sender, EventArgs e)
            {
                if (toHex.Checked)
                {
                    for (int i = 0; i < pldsItems.Controls.Count; i += 2)
                    {
                        pldsItems.Controls[i + 1].Text = "0x" + HEX_converter.ToHexString(Calculator.ParseInteger(pldsItems.Controls[i + 1].Text));
                    }
                }
                else
                {
                    for (int i = 0; i < pldsItems.Controls.Count; i += 2)
                    {
                        pldsItems.Controls[i + 1].Text = Calculator.ParseInteger(pldsItems.Controls[i + 1].Text).ToString();
                    }
                }
            }
            /// <summary>
            /// When the apply button is clicked, update the payload values and set the form dialog result
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            void apply_Click(object sender, EventArgs e)
            {
                updateValues();
                DialogResult = DialogResult.OK;
            }
        }
        /// <summary>
        /// Fast script selection button
        /// </summary>
        internal class ScrFastSelButton : Button
        {
            /// <summary>
            /// Script file name associated to this button
            /// </summary>
            public string fileName;
        }
        /// <summary>
        /// Fast script selection tab page
        /// </summary>
        internal class ScrFastSelTabPage : TabPage
        {
            /// <summary>
            /// Name of the directory associated to the tab page
            /// </summary>
            public string dirName;

            public ScrFastSelTabPage(string tabName)
                : base(tabName)
            {
            }
        }
        /// <summary>
        /// Fast script directory selection menu item
        /// </summary>
        internal class ScrFastDirSelMenuItem : ToolStripItem
        {
            /// <summary>
            /// Directory related tab page index
            /// </summary>
            public int TabIndex;

            public ScrFastDirSelMenuItem(string text, EventHandler onClick, int tabIdnex)
                : base(text, null, onClick)
            {
                TabIndex = tabIdnex;
            }

            public override string ToString()
            {
                return base.ToString();
            }
        }

        /// <summary>
        /// Script engine instance - executes command lines and provides feedback
        /// </summary>
        ScrMainModule scrEngine;

        bool noGUI = false;
        public bool NoGUI
        {
            get
            {
                return noGUI;
            }
            set
            {
                noGUI = value;
            }
        }

        /// <summary>
        /// Last error status
        /// </summary>
        string eStat = "";

        public delegate OMXComponent[] GetAvailableOMXComponentsDelegate();
        public delegate CommLink.CommLink GetActiveCommLinkDelegate();
        public delegate void CreateDefaultComLinkDelegate(bool ask);
        delegate void EmptyDelegate();

        CommLink.CommLink commObjRef = null;
        CommLink.CommLink.ConnectionStatusEvent cnStat = null;
        ScrMainModule.ScriptEvent scrDoneEv = null;
        ScrMainModule.ScriptEvent scrCmptChgEv = null;
        ScrMainModule.ScriptEvent scrTerminating = null;

        GetAvailableOMXComponentsDelegate _GetAvailableOMXComponents = null;
        GetActiveCommLinkDelegate _GetActiveCommLink = null;
        CreateDefaultComLinkDelegate _CreateDefComLink;

        Form prntForm = null;

        /// <summary>
        /// Public constructor
        /// </summary>
        /// <param name="gtpProperties">Tab page properties array - to extract IAUECSettings and component id, struct id, port number from</param>
        /// <param name="messages">Available messages array</param>
        /// <param name="commObj">CommLink communication ibject to use as message medium</param>
        public ScriptingModule(GetAvailableOMXComponentsDelegate GetAvailableOMXComponents, GetActiveCommLinkDelegate GetActiveCommLink, bool miniMode, CreateDefaultComLinkDelegate CreateDefComLink, Form prnt)
        {            
            InitializeComponent();

            scrEdit.OnLineChange += new ScrEditBox.UIUpdateDelegate(scrEdit_OnLineChange);
            scrEdit.OnFileSaved += new ScrEditBox.UIUpdateDelegate(scrEdit_OnFileSaved);

            prntForm = prnt;
            MiniMode = miniMode;
            _GetAvailableOMXComponents = GetAvailableOMXComponents;
            _GetActiveCommLink = GetActiveCommLink;
            _CreateDefComLink = CreateDefComLink;

            if (_GetAvailableOMXComponents != null && _GetActiveCommLink != null)
            {
                OMXComponent[] omxComps = _GetAvailableOMXComponents();
                CommLink.CommLink commObj = _GetActiveCommLink();

                if(cnStat == null)
                    cnStat = new CommLink.CommLink.ConnectionStatusEvent(commObj_OnConnectionStatusEvent);
                commObj.OnConnectionStatusEvent += cnStat;
                refreshUIDataBindings(omxComps, commObj);
            }
            else
            {
                Close();
            }
        }

        void scrEdit_OnFileSaved(string text)
        {
            tssFileSaveStatus.Text = text;
        }

        void scrEdit_OnLineChange(string text)
        {
            tssLineNumber.Text = "At line: " + text;
        }

        ~ScriptingModule()
        {
            scrEngine.ScrMainModuleStop();
            scrEngine_OnScriptModuleTerminatig("");
        }

        void scrEngine_OnScriptModuleTerminatig(string ErrorStatus)
        {
            if (scrDoneEv != null && scrEngine != null)
            {
                scrEngine.components.rteCmn.OnScriptDone -= scrDoneEv;
                scrDoneEv = null;
            }

            if (scrCmptChgEv != null && scrEngine != null)
            {
                scrEngine.components.rteCmn.OnScriptComponentsChanged -= scrCmptChgEv;
                scrCmptChgEv = null;
            }

            if (scrTerminating != null && scrEngine != null)
            {
                scrEngine.components.rteCmn.OnScriptModuleTerminatig -= scrTerminating;
                scrTerminating = null;
            }

            if (cnStat != null && commObjRef != null)
            {
                commObjRef.OnConnectionStatusEvent -= cnStat;
                cnStat = null;
            }
        } 

        void commObj_OnConnectionStatusEvent(CommLinkAbstract.ConnectionStates eState)
        {
            if ((eState == CommLinkAbstract.ConnectionStates.NotConnected || eState == CommLinkAbstract.ConnectionStates.ServerError) && tssExecStatus.Text != "Connection lost!")
            {
                tssExecStatus.Text = "Connection lost!";
                if (!noGUI)
                {
                    if (MessageBox.Show("Close scripting?", "Connection lost!", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                    {
                        if (InvokeRequired)
                            Invoke(new EmptyDelegate(Close));
                        else
                            Close();
                    }
                }
                else
                {
                    Close();
                }
            }
        }

        void scrEngine_OnScriptComponentsChanged(string ErrorStatus)
        {
            if (InvokeRequired)
            {
                Invoke(new ScrMainModule.ScriptEvent(scrEngine_OnScriptComponentsChanged), new object[] { ErrorStatus });
            }
            else
            {
                updateUI();
            }
        }

        void scrEngine_OnScriptDone(string ErrorStatus)
        {
            eStat = ErrorStatus;
            if (InvokeRequired)
            {
                Invoke(new ScrMainModule.ScriptEvent(scrEngine_OnScriptDone), new object[] { ErrorStatus });
            }
            else
            {
                tssExecStatus.Text = ErrorStatus;
                if (!ErrorStatus.Contains("Executing: "))
                {
                    updateUI();
                    if (!noGUI)
                    {
                        if ((!MiniMode && !scrEngine.components.rteCmn.SilentRun) || ErrorStatus.Contains("Failed"))
                            MessageBox.Show("Script finished: " + ErrorStatus);
                    }
                }
            }
        }

        const int BtnNamePadding = 25;

        /// <summary>
        /// Sets the UI data bindings to the specified objects and initializes UI to display them
        /// </summary>
        /// <param name="omxComps">Available OMX components and their configuration structures</param>
        /// <param name="commObj">Communication object to bind the messaging server to</param>
        void refreshUIDataBindings(OMXComponent[] omxComps, CommLink.CommLink commObj)
        {
            scrEdit.AutoScroll = true;

            if (MiniMode)
            {
                splitContainerScriptEditting.Panel1Collapsed = true;

                scrEdit.rtMainEdit.Text = "Ctrl + left click a button to load script without executing\n" + 
                                            "Ctrl + g to go to line\n" + 
                                            "Ctrl + s to quick save file\n" +
                                            "Ctrl + o to open file\n";

                displayToolStripMenuItem.Text = "Display runtime variables";

                DirectoryInfo dirScript = null;
                try
                {
                    dirScript = new DirectoryInfo(ScriptModule.Properties.Settings.Default.FastScriptMenuFolder);
                }
                catch
                {
                    dirScript = null;
                }
                if (dirScript == null || !dirScript.Exists)
                {
                    dirScript = new DirectoryInfo(Application.StartupPath + SCRIPT_DIR);
                    if (!dirScript.Exists)
                        dirScript.Create();

                    ScriptModule.Properties.Settings.Default.FastScriptMenuFolder = dirScript.FullName;
                    ScriptModule.Properties.Settings.Default.Save();
                }
                Text = dirScript.FullName;
                DirectoryInfo[] dirSubScript = dirScript.GetDirectories();

                scripts = dirScript.GetFiles();
                if (scripts.Length > 0)
                {
                    ScrFastSelTabPage tbPg = new ScrFastSelTabPage("General");
                    tbPg.dirName = dirScript.Name;
                    tabScriptSelect.TabPages.Add(tbPg);
                    int tabNum = tabScriptSelect.TabCount - 1;
                    tabScriptSelect.TabPages[tabNum].AutoScroll = true;
                    int maxBtnNameLen = 0;
                    for (int i = 0; i < scripts.Length; i++)
                    {
                        if (scripts[i].Extension == ".scp")
                        {
                            ScrFastSelButton scriptBtn = new ScrFastSelButton();
                            scriptBtn.fileName = scripts[i].Name;
                            scriptBtn.Text = scripts[i].Name.Remove(0,2).Replace("_", " ").Replace(".scp","");

                            Graphics gfx = scriptBtn.CreateGraphics();
                            SizeF strDim = gfx.MeasureString(scriptBtn.Text, scriptBtn.Font);
                            if (scriptBtn.Size.Width < strDim.Width + BtnNamePadding && maxBtnNameLen < strDim.Width + BtnNamePadding)
                            {
                                maxBtnNameLen = (int)strDim.Width + BtnNamePadding;
                            }
                            else if (maxBtnNameLen < scriptBtn.Size.Width)
                            {
                                maxBtnNameLen = scriptBtn.Size.Width;
                            }

                            scriptBtn.Click += new EventHandler(scriptBtn_Click);
                            if (tabScriptSelect.TabPages[tabNum].Controls.Count > 0)
                                scriptBtn.Location = new Point(0, tabScriptSelect.TabPages[tabNum].Controls[tabScriptSelect.TabPages[tabNum].Controls.Count - 1].Location.Y +
                                                                    tabScriptSelect.TabPages[tabNum].Controls[tabScriptSelect.TabPages[tabNum].Controls.Count - 1].Size.Height + 1);
                            else
                                scriptBtn.Location = new Point(0, 0);
                            tabScriptSelect.TabPages[tabNum].Controls.Add(scriptBtn);
                        }
                    }

                    for (int i = 0; i < tabScriptSelect.TabPages[tabNum].Controls.Count; i++)
                    {
                        tabScriptSelect.TabPages[tabNum].Controls[i].Size = new Size(maxBtnNameLen, tabScriptSelect.TabPages[tabNum].Controls[i].Size.Height);
                    }
                }

                for (int k = 0; k < dirSubScript.Length; k++)
                {
                    FileInfo[] tmpScFile = dirSubScript[k].GetFiles();
                    if (tmpScFile.Length > 0)
                    {
                        FileInfo[] nScFileRef = new FileInfo[scripts.Length + tmpScFile.Length];
                        scripts.CopyTo(nScFileRef, 0);
                        tmpScFile.CopyTo(nScFileRef, scripts.Length);
                        scripts = nScFileRef;
                        ScrFastSelTabPage tbPg = new ScrFastSelTabPage(dirSubScript[k].Name.Remove(0,2).Replace("_"," "));
                        tbPg.dirName = dirSubScript[k].Name;
                        tabScriptSelect.TabPages.Add(tbPg);
                        int tabNum = tabScriptSelect.TabCount - 1;
                        tabScriptSelect.TabPages[tabNum].AutoScroll = true;
                        int maxBtnNameLen = 0;
                        for (int i = 0; i < tmpScFile.Length; i++)
                        {
                            if (tmpScFile[i].Extension == ".scp")
                            {
                                ScrFastSelButton scriptBtn = new ScrFastSelButton();
                                scriptBtn.fileName = tmpScFile[i].Name;
                                scriptBtn.Text = tmpScFile[i].Name.Remove(0, 2).Replace("_", " ").Replace(".scp", "");

                                Graphics gfx = scriptBtn.CreateGraphics();
                                SizeF strDim = gfx.MeasureString(scriptBtn.Text, scriptBtn.Font);
                                if (scriptBtn.Size.Width < strDim.Width + BtnNamePadding && maxBtnNameLen < strDim.Width + BtnNamePadding)
                                {
                                    maxBtnNameLen = (int)strDim.Width + BtnNamePadding;
                                }
                                else if (maxBtnNameLen < scriptBtn.Size.Width)
                                {
                                    maxBtnNameLen = scriptBtn.Size.Width;
                                }
                                scriptBtn.Click += new EventHandler(scriptBtn_Click);

                                if (tabScriptSelect.TabPages[tabNum].Controls.Count > 0)
                                    scriptBtn.Location = new Point(0, tabScriptSelect.TabPages[tabNum].Controls[tabScriptSelect.TabPages[tabNum].Controls.Count - 1].Location.Y +
                                                                        tabScriptSelect.TabPages[tabNum].Controls[tabScriptSelect.TabPages[tabNum].Controls.Count - 1].Size.Height + 1);
                                else
                                    scriptBtn.Location = new Point(0, 0);
                                tabScriptSelect.TabPages[tabNum].Controls.Add(scriptBtn);
                            }
                        }

                        for (int i = 0; i < tabScriptSelect.TabPages[tabNum].Controls.Count; i++)
                        {
                            tabScriptSelect.TabPages[tabNum].Controls[i].Size = new Size(maxBtnNameLen, tabScriptSelect.TabPages[tabNum].Controls[i].Size.Height);
                        }
                    }
                }

                scrEdit.AutoScroll = true;

                for (int i = 0; i < menuStripScript.Items.Count; i++)
                {
                    if (menuStripScript.Items[i].Text == "Scripts")
                    {
                        menuStripScript.Items.RemoveAt(i);
                        break;
                    }
                }

                /*
                ToolStripMenuItem tsi = new ToolStripMenuItem("Scripts");
                EventHandler scrDirSeleh = new EventHandler(ScriptDirectorySelection);

                for (int i = 0; i < tabScriptSelect.TabPages.Count; i++)
                {
                    tsi.DropDownItems.Add(new ScrFastDirSelMenuItem(tabScriptSelect.TabPages[i].Text, scrDirSeleh, i));
                }
                if (tsi.DropDownItems.Count > 0)
                    menuStripScript.Items.Add(tsi);
                */
            }
            else
            {
                splitContainerScriptView.Panel1Collapsed = true;

                displayToolStripMenuItem.Text = "Hide runtime variables";

                scrEdit.rtMainEdit.Text = "Ctrl + g to go to line\n" +
                                            "Ctrl + s to quick save file\n" +
                                            "Ctrl + o to open file\n";
            }

            #region Set up context menus
            ContextMenuStrip tmpCtxMenu = new ContextMenuStrip();
            tmpCtxMenu.ShowCheckMargin = true;
            EventHandler eh = new EventHandler(ContextMenuHandler);
            tmpCtxMenu.Items.Add(CTX_MENU_HEXVIEW, null, eh);

            lbMessages.ContextMenuStrip = tmpCtxMenu;
            tvPldStructs.ContextMenuStrip = tmpCtxMenu;
            #endregion

            List<ScrMainModule.OMXCompScrHdlr> compLs = new List<ScrMainModule.OMXCompScrHdlr>();
            List<GenMSG> messages = new List<GenMSG>();
            for (int ikOmx = 0; ikOmx < omxComps.Length; ikOmx++)
            {
                ScrMainModule.OMXCompScrHdlr tmpCom = new ScrMainModule.OMXCompScrHdlr();
                tmpCom.OMXCompName = omxComps[ikOmx].omxName;
                #region Get IAUECSettings for the scripting module initialization
                GenPayloadStruct[] tmpPldStr = new GenPayloadStruct[omxComps[ikOmx].gtpProperties.Length];
                for (int i = 0; i < tmpPldStr.Length; i++)
                {

                    IAEUCSetting[] settAr = omxComps[ikOmx].gtpProperties[i].GetSettingArray;
                    /*
                    for (int k = 0; k < settAr.Length; k++)
                    {
                        settAr[k].AEUC_ResetToDefault();
                    }
                    */
                    if (settAr.Length > 0)
                        tmpPldStr[i] = new GenPayloadStruct(omxComps[ikOmx].gtpProperties[i].TabName,
                                                            settAr,
                                                            omxComps[ikOmx].gtpProperties[i].TabRelCompId,
                                                            omxComps[ikOmx].gtpProperties[i].TabId,
                                                            omxComps[ikOmx].gtpProperties[i].TabIdExtra);
                    else
                        tmpPldStr[i] = new GenPayloadStruct(omxComps[ikOmx].gtpProperties[i].TabName,
                                                            null,
                                                            omxComps[ikOmx].gtpProperties[i].TabRelCompId,
                                                            omxComps[ikOmx].gtpProperties[i].TabId,
                                                            omxComps[ikOmx].gtpProperties[i].TabIdExtra);
                }
                tmpCom.scrPldStructs = tmpPldStr;
                #endregion

                #region Get OMX Component messaging items
                for (int i = 0; i < omxComps[ikOmx].messages.Length; i++)
                {
                    if (!messages.Contains(omxComps[ikOmx].messages[i]))
                    {
                        messages.Add(omxComps[ikOmx].messages[i]);
                    }
                }
                #endregion

                compLs.Add(tmpCom);
            }
            scrEngine = new ScrMainModule(commObj, messages.ToArray(), compLs.ToArray(), new ScrMainModule.ScriptExec(createDefCommObject));

            if (scrDoneEv == null)
                scrDoneEv = new ScrMainModule.ScriptEvent(scrEngine_OnScriptDone);
            if (scrCmptChgEv == null)
                scrCmptChgEv = new ScrMainModule.ScriptEvent(scrEngine_OnScriptComponentsChanged);
            if (scrTerminating == null)
                scrTerminating = new ScrMainModule.ScriptEvent(scrEngine_OnScriptModuleTerminatig);

            scrEngine.components.rteCmn.OnScriptModuleTerminatig += scrTerminating;
            scrEngine.components.rteCmn.OnScriptDone += scrDoneEv;
            scrEngine.components.rteCmn.OnScriptComponentsChanged += scrCmptChgEv;

            scrEngine.components.rteCmn.scrSetUpProgBar = new ScrMainModule.ScriptSetUpProgBar(progressSetUp);
            scrEngine.components.rteCmn.scrStepProgBar = new ScrMainModule.ScriptStepProgBar(progressStep);
            scrEngine.components.rteCmn.scrRemProgBar = new ScrMainModule.ScriptRemoveProgBar(progressRemove);

            tssExecStatus.Text = "Script idle";
            scrEdit.SetBoundScrEngine(scrEngine);
            initializeUI();
        }

        /// <summary>
        /// Reset the communication object
        /// </summary>
        /// <param name="omxComps">Available OMX components and their configuration structures</param>
        /// <param name="commObj">Communication object to bind the messaging server to</param>
        void resetCommObject(OMXComponent[] omxComps, CommLink.CommLink commObj)
        {
            List<ScrMainModule.OMXCompScrHdlr> compLs = new List<ScrMainModule.OMXCompScrHdlr>();
            List<GenMSG> messages = new List<GenMSG>();
            for (int ikOmx = 0; ikOmx < omxComps.Length; ikOmx++)
            {
                ScrMainModule.OMXCompScrHdlr tmpCom = new ScrMainModule.OMXCompScrHdlr();
                tmpCom.OMXCompName = omxComps[ikOmx].omxName;
                #region Get IAUECSettings for the scripting module initialization
                GenPayloadStruct[] tmpPldStr = new GenPayloadStruct[omxComps[ikOmx].gtpProperties.Length];
                for (int i = 0; i < tmpPldStr.Length; i++)
                {

                    IAEUCSetting[] settAr = omxComps[ikOmx].gtpProperties[i].GetSettingArray;
                    /*
                    for (int k = 0; k < settAr.Length; k++)
                    {
                        settAr[k].AEUC_ResetToDefault();
                    }
                    */
                    if (settAr.Length > 0)
                        tmpPldStr[i] = new GenPayloadStruct(omxComps[ikOmx].gtpProperties[i].TabName,
                                                            settAr,
                                                            omxComps[ikOmx].gtpProperties[i].TabRelCompId,
                                                            omxComps[ikOmx].gtpProperties[i].TabId,
                                                            omxComps[ikOmx].gtpProperties[i].TabIdExtra);
                    else
                        tmpPldStr[i] = new GenPayloadStruct(omxComps[ikOmx].gtpProperties[i].TabName,
                                                            null,
                                                            omxComps[ikOmx].gtpProperties[i].TabRelCompId,
                                                            omxComps[ikOmx].gtpProperties[i].TabId,
                                                            omxComps[ikOmx].gtpProperties[i].TabIdExtra);
                }
                tmpCom.scrPldStructs = tmpPldStr;
                #endregion

                #region Get OMX Component messaging items
                for (int i = 0; i < omxComps[ikOmx].messages.Length; i++)
                {
                    if (!messages.Contains(omxComps[ikOmx].messages[i]))
                    {
                        messages.Add(omxComps[ikOmx].messages[i]);
                    }
                }
                #endregion

                compLs.Add(tmpCom);
            }
            scrEngine = new ScrMainModule(commObj, messages.ToArray(), compLs.ToArray(), new ScrMainModule.ScriptExec(createDefCommObject));

            if (scrDoneEv == null)
                scrDoneEv = new ScrMainModule.ScriptEvent(scrEngine_OnScriptDone);
            if(scrCmptChgEv == null)
                scrCmptChgEv = new ScrMainModule.ScriptEvent(scrEngine_OnScriptComponentsChanged);
            if (scrTerminating == null)
                scrTerminating = new ScrMainModule.ScriptEvent(scrEngine_OnScriptModuleTerminatig);

            scrEngine.components.rteCmn.OnScriptModuleTerminatig += scrTerminating;
            scrEngine.components.rteCmn.OnScriptDone += scrDoneEv;
            scrEngine.components.rteCmn.OnScriptComponentsChanged += scrCmptChgEv;

            scrEngine.components.rteCmn.scrSetUpProgBar = new ScrMainModule.ScriptSetUpProgBar(progressSetUp);
            scrEngine.components.rteCmn.scrStepProgBar = new ScrMainModule.ScriptStepProgBar(progressStep);
            scrEngine.components.rteCmn.scrRemProgBar = new ScrMainModule.ScriptRemoveProgBar(progressRemove);

            tssExecStatus.Text = "Script idle";
            scrEdit.SetBoundScrEngine(scrEngine);
            initializeUI();
        }

        /// <summary>
        /// Initialize the UI of the script components display - actions, messages and payload structs
        /// </summary>
        void initializeUI()
        {
            lbScrActions.Items.Clear();
            lbScrActions.Items.AddRange(scrEngine.components.scrActions);

            lbMessages.Items.Clear();
            lbMessages.Items.AddRange(scrEngine.components.scrMessages);

            tvPldStructs.Nodes.Clear();

            for (int iCom = 0; iCom < scrEngine.components.compHdls.Length; iCom++)
            {
                TreeNode comNode = new TreeNode(scrEngine.components.compHdls[iCom].OMXCompName);
                for (int i = 0; i < scrEngine.components.compHdls[iCom].scrPldStructs.Length; i++)
                {
                    GenPldStructTNode tmpNode = new GenPldStructTNode(scrEngine.components.compHdls[iCom].scrPldStructs[i], scrEdit.rtMainEdit);
                    for (int k = 0; k < scrEngine.components.compHdls[iCom].scrPldStructs[i].structContentsStringRep.Length; k++)
                    {
                        TreeNode tmpNodeChld = new TreeNode(scrEngine.components.compHdls[iCom].scrPldStructs[i].structContentsStringRep[k].dispName);
                        tmpNode.Nodes.Add(tmpNodeChld);
                    }
                    comNode.Nodes.Add(tmpNode);
                }
                tvPldStructs.Nodes.Add(comNode);
            }
        }
        /// <summary>
        /// Stops the messaging center
        /// </summary>
        void scrEngineReset()
        {
            scrEngine.ScrMainModuleStop();
        }
        /// <summary>
        /// Reloads the scripting interface and communication
        /// </summary>
        /// <param name="omxComps">Available OMX components and their configuration structures</param>
        /// <param name="commObj">Communication object to bind the messaging server to</param>
        void reloadUI(OMXComponent[] omxComps, CommLink.CommLink commObj)
        {
            tabScriptSelect.TabPages.Clear();

            scrEngineReset();

            refreshUIDataBindings(omxComps, commObj);
        }

        /// <summary>
        /// Refreshes the UI of the script components display - actions, messages and payload structs
        /// </summary>
        void updateUI()
        {
            if (tvPldStructs.Nodes.Count != scrEngine.components.compHdls.Length)
                throw new Exception("Script module: unexpected runtime error!\nComponent objects changed during execution");

            for (int iCom = 0; iCom < scrEngine.components.compHdls.Length; iCom++)
            {

                TreeNode comNode = tvPldStructs.Nodes[iCom];
                comNode.Nodes.Clear();
                for (int i = 0; i < scrEngine.components.compHdls[iCom].scrPldStructs.Length; i++)
                {
                    GenPldStructTNode tmpNode = new GenPldStructTNode(scrEngine.components.compHdls[iCom].scrPldStructs[i], scrEdit.rtMainEdit);
                    for (int k = 0; k < scrEngine.components.compHdls[iCom].scrPldStructs[i].structContentsStringRep.Length; k++)
                    {
                        TreeNode tmpNodeChld = new TreeNode(scrEngine.components.compHdls[iCom].scrPldStructs[i].structContentsStringRep[k].dispName);
                        tmpNode.Nodes.Add(tmpNodeChld);
                    }
                    comNode.Nodes.Add(tmpNode);
                }
            }
        }

        #region Script components tool tips, menus and event handling

        #region Shared context menu items

        bool hexFormatView = false;
        const string CTX_MENU_HEXVIEW = "Hex format";

        private void ContextMenuHandler(object sender, EventArgs ea)
        {
            hexFormatView = !hexFormatView;
            ToolStripMenuItem tmpItem = (ToolStripMenuItem)sender;
            tmpItem.Checked = hexFormatView;
        }

        #endregion

        #region Script action commands tool tip

        int lbScrActionsSelIndx = -1;
        ToolTip lbScrActionsInfo = new ToolTip();

        private void lbScrActions_MouseMove(object sender, MouseEventArgs e)
        {
            int selIndx = lbScrActions.IndexFromPoint(e.Location);
            if (selIndx > -1 && lbScrActionsSelIndx != selIndx)
            {
                lbScrActionsInfo.Hide(this);
                lbScrActionsSelIndx = selIndx;
                ScrBasicAction tmp = (ScrBasicAction)lbScrActions.Items[selIndx];
                lbScrActionsInfo.Show(tmp.UsageSummary, this, lbScrActions.PointToScreen(e.Location));
            }
        }

        private void lbScrActions_MouseLeave(object sender, EventArgs e)
        {
            lbScrActionsInfo.Hide(this);
            lbScrActionsSelIndx = -1;
        }

        private void lbScrActions_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            int selIndx = lbScrActions.IndexFromPoint(e.Location);
            ScrBasicAction tmp = (ScrBasicAction)lbScrActions.Items[selIndx];
            scrEdit.rtMainEdit.AppendText(tmp.DisplayName + " ");
        }

        #endregion

        #region Messages tool tip

        int lbMessagesSelIndx = -1;
        ToolTip lbMessagesInfo = new ToolTip();

        private void lbMessages_MouseMove(object sender, MouseEventArgs e)
        {
            int selIndx = lbMessages.IndexFromPoint(e.Location);
            if (selIndx > -1 && lbMessagesSelIndx != selIndx)
            {
                tvPldStructsInfo.Hide(this);
                lbMessagesSelIndx = selIndx;
                GenMSG tmp = (GenMSG)lbMessages.Items[selIndx];
                string toolTipText;

                if (hexFormatView)
                    toolTipText = "Id: " + tmp.msgId.ToString() + 
                        "(0x" + HEX_converter.ToHexString(tmp.msgId.UID) + ");" + 
                        "Status: " + tmp.msgStatus.ToString() + "(0x" + HEX_converter.ToHexString(tmp.msgStatus.UID) + ");";
                else
                    toolTipText = "Id: " + tmp.msgId.ToString() + 
                        "(" + tmp.msgId.UID.ToString() + ");" + 
                        "Status: " + tmp.msgStatus.ToString() + "(" + tmp.msgStatus.UID.ToString() + ");";

                lbMessagesInfo.Show(toolTipText, this, lbMessages.PointToScreen(e.Location));
            }
        }

        private void lbMessages_MouseLeave(object sender, EventArgs e)
        {
            lbMessagesInfo.Hide(this);
            lbMessagesSelIndx = -1;
        }

        private void lbMessages_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            int selIndx = lbMessages.IndexFromPoint(e.Location);
            GenMSG tmp = (GenMSG)lbMessages.Items[selIndx];
            scrEdit.rtMainEdit.AppendText(tmp.msgDisplayName + " ");
        }

        #endregion

        #region Payload structs tool tip

        TreeNode tvPldStructslastSelNode = null;
        ToolTip tvPldStructsInfo = new ToolTip();

        private void tvPldStructs_MouseMove(object sender, MouseEventArgs e)
        {
            TreeNode selNode = tvPldStructs.GetNodeAt(e.Location);
            if (selNode != null && tvPldStructslastSelNode != selNode)
            {
                tvPldStructsInfo.Hide(this);
                tvPldStructslastSelNode = selNode;
                if (tvPldStructslastSelNode.GetType() == typeof(GenPldStructTNode))
                {
                    GenPayloadStruct tmp = ((GenPldStructTNode)selNode).pldStruct;
                    tvPldStructsInfo.Show(tmp.ContentsString(hexFormatView), this, tvPldStructs.PointToScreen(e.Location));
                }
            }
        }

        private void tvPldStructs_MouseLeave(object sender, EventArgs e)
        {
            tvPldStructsInfo.Hide(this);
            tvPldStructslastSelNode = null;
        }

        private void tvPldStructs_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            string insrtStr = "";
            GenPldStructTNode tmpNode;
            if (e.Node.GetType() != typeof(GenPldStructTNode))
            {
                insrtStr = "." + e.Node.Text;
                tmpNode = (GenPldStructTNode)e.Node.Parent;
                if (tmpNode != null)
                {
                    insrtStr = tmpNode.Text + insrtStr;

                    if (tmpNode.Parent != null)
                        insrtStr = tmpNode.Parent.Text + "." + insrtStr;
                    
                    scrEdit.rtMainEdit.AppendText(insrtStr + " ");
                }
            }
        }

        #endregion

        #region Mini mode handlers

        public static string SCRIPT_DIR = "\\scripts";
        bool MiniMode = false;
        FileInfo[] scripts = null;

        private void ScriptDirectorySelection(object sender, EventArgs ea)
        {
            ScrFastDirSelMenuItem tmpItem = (ScrFastDirSelMenuItem)sender;

            tabScriptSelect.SelectTab(tmpItem.TabIndex);
        }

        void  scriptBtn_Click(object sender, EventArgs e)
        {
            MouseEventArgs mouseArgs = (MouseEventArgs)e;
            ScrFastSelButton callee = (ScrFastSelButton)sender;
            string dir = ((ScrFastSelTabPage)callee.Parent).dirName;
            for (int i = 0; i < scripts.Length; i++)
            {
                if (scripts[i].Name == callee.fileName && scripts[i].Directory.Name == dir)
                {
                    scrEdit.LoadScriptFile(scripts[i]);
                    if (ModifierKeys == Keys.Control)
                        scrEdit.LoadScriptFile(scripts[i]);
                    else
                        scrEdit.ScriptExecuteThreaded();
                }
            }
        }

        #endregion

        #endregion

        void uiSettRefresh()
        {
            if (InvokeRequired)
            {
                Invoke(new EmptyDelegate(uiSettRefresh));
            }
            else
            {
                if (_GetAvailableOMXComponents != null && _GetActiveCommLink != null)
                {
                    OMXComponent[] omxComps = _GetAvailableOMXComponents();
                    CommLink.CommLink commObj = _GetActiveCommLink();
                    commObjRef = commObj;

                    reloadUI(omxComps, commObj);
                }
                else
                {
                    Close();
                }
            }
        }

        private void tssRefreshUI_Click(object sender, EventArgs e)
        {
            uiSettRefresh();
        }

        /// <summary>
        /// Createa new default communication object
        /// </summary>
        private void createDefCommObject()
        {
            if (_CreateDefComLink != null)
            {
                _CreateDefComLink(false);
            }

            if (_GetAvailableOMXComponents != null && _GetActiveCommLink != null)
            {
                OMXComponent[] omxComps = _GetAvailableOMXComponents();
                CommLink.CommLink commObj = _GetActiveCommLink();
                commObjRef = commObj;

                if (cnStat == null)
                    cnStat = new CommLink.CommLink.ConnectionStatusEvent(commObj_OnConnectionStatusEvent);
                commObj.OnConnectionStatusEvent += cnStat;
                resetCommObject(omxComps, commObj);
            }
        }

        private void componentSettingsRefreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            uiSettRefresh();
        }

        private void fastScriptDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                ScriptModule.Properties.Settings.Default.FastScriptMenuFolder = fbd.SelectedPath;
                ScriptModule.Properties.Settings.Default.Save();
                uiSettRefresh();
            }
        }

        private void generateCSourceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ScriptSourcesify scrGenSource = new ScriptSourcesify(scrEdit);
            scrEngine.components.rteCmn.OnScriptSourceGenerated += new ScrMainModule.ScriptEvent(scrGenSource.sourceGenerated);
            scrGenSource.ShowDialog();
        }

        void scrEngine_OnScriptSourceGenerated(string ErrorStatus)
        {
            throw new NotImplementedException();
        }

        private void displayToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (displayToolStripMenuItem.Text == "Display runtime variables")
            {
                if (MiniMode)
                {
                    tvPldStructs.Dock = DockStyle.Fill;
                    tvPldStructs.BringToFront();
                }
                displayToolStripMenuItem.Text = "Hide runtime variables";
                splitContainerScriptEditting.Panel1Collapsed = false;
            }
            else
            {
                displayToolStripMenuItem.Text = "Display runtime variables";
                splitContainerScriptEditting.Panel1Collapsed = true;
            }
        }

        private void oMXALMainViewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (prntForm != null)
            {
                prntForm.WindowState = FormWindowState.Normal;
                prntForm.Focus();
            }
        }

        #region Script progress bar handle

        private void showProgBar()
        {
            if (!noGUI)
            {
                if (InvokeRequired)
                {
                    Invoke(new EmptyDelegate(showProgBar));
                }
                else
                {
                    scrProgBar.Visible = true;
                    scrProgBar.BringToFront();
                }
            }
        }

        private void hideProgBar()
        {
            if (!noGUI)
            {
                if (InvokeRequired)
                {
                    Invoke(new EmptyDelegate(hideProgBar));
                }
                else
                {
                    scrProgBar.Visible = false;
                    scrProgBar.SendToBack();
                }
            }
        }

        const int progBarExpnHeight = 30;

        private void shrinkProgBar()
        {
            if (!noGUI)
            {
                if (InvokeRequired)
                {
                    Invoke(new EmptyDelegate(shrinkProgBar));
                }
                else
                {
                    scrProgBar.Top += progBarExpnHeight;
                    scrProgBar.Height -= progBarExpnHeight;
                }
            }
        }

        private void expandProgBar()
        {
            if (!noGUI)
            {
                if (InvokeRequired)
                {
                    Invoke(new EmptyDelegate(expandProgBar));
                }
                else
                {
                    scrProgBar.Top -= progBarExpnHeight;
                    scrProgBar.Height += progBarExpnHeight;
                }
            }
        }

        public ProgressBars.ProgBarsHdl progressSetUp(string progTitle, int numSteps)
        {
            if (!noGUI)
            {
                showProgBar();

                ProgressBars.ProgBarsHdl progHdl = scrProgBar.CreateProgressBar(progTitle);

                progHdl.SetMinimum(0);
                progHdl.SetMaximum(numSteps);
                progHdl.SetStep(1);

                if (scrProgBar.GetActiveProgressBars() > 2)
                    expandProgBar();

                return progHdl;
            }

            return null;
        }

        public void progressStep(ProgressBars.ProgBarsHdl progHdl)
        {
            if (!noGUI)
            {
                progHdl.Step();
            }
        }

        public void progressRemove(ProgressBars.ProgBarsHdl progHdl)
        {
            if (!noGUI)
            {
                scrProgBar.DestroyProgressBar(progHdl);

                if (scrProgBar.GetActiveProgressBars() == 0)
                    hideProgBar();
                else
                    shrinkProgBar();
            }
        }

        #endregion

        #region Pulbic API for no GUI control of Scripting Moudle
        
        /// <summary>
        /// Error report structure containing error code and message
        /// </summary>
        public struct ScrErrorReport
        {
            public uint Code;
            public string Message;
        }

        #region Initialization reoutines

        /// <summary>
        /// Flag for first time initialization requirements
        /// </summary>
        bool firstRun = true;
        /// <summary>
        /// Printing function
        /// </summary>
        ScriptPrint printFunc = null;
        /// <summary>
        /// If the user requests to run a script from a specific line memo it here
        /// </summary>
        int runFromLine = 0;
        /// <summary>
        /// Performs first run initializations
        /// </summary>
        void firstRunInit()
        {
            if (firstRun)
            {
                firstRun = false;
                uiSettRefresh();
                scrEngine.RegisterPrintFunction(printFunc);
            }
        }
        /// <summary>
        /// Register a printing function for the script commands
        /// </summary>
        /// <param name="printF">Print function delegate</param>
        public void RegisterPrintFunc(ScriptPrint printF)
        {
            printFunc = printF;
        }

        #endregion

        #region Script execution commands

        /// <summary>
        /// Executes a specified script file
        /// </summary>
        /// <param name="scrFile">File path</param>
        /// <returns>Error status of execution</returns>
        public uint executeScriptFileOld(string scrFile)
        {
            ScrErrorReport status = executeScriptFile(scrFile);

            return status.Code;
        }
        /// <summary>
        /// Executes a specified script file
        /// </summary>
        /// <param name="scrFile">File path</param>
        /// <returns>Error status of execution</returns>
        public ScrErrorReport executeScriptFile(string scrFile)
        {
            ScrErrorReport status = new ScrErrorReport();
            status.Code = 0;
            status.Message = "Success";
            try
            {
                FileInfo scrExecFile = new FileInfo(scrFile);
                if (!scrExecFile.Exists)
                {
                    scrExecFile = new FileInfo(ScriptModule.Properties.Settings.Default.FastScriptMenuFolder + "\\" + scrFile);
                }
                if (scrExecFile.Exists)
                {
                    firstRunInit();
                    while (scrEdit.executing) ;
                    scrEdit.LoadScriptFile(scrExecFile);
                    scrEdit.ScriptExecute(runFromLine);
                    runFromLine = 0;
                }
                else
                {
                    if (!MiniMode && !noGUI)
                        MessageBox.Show("Invalid file: " + scrExecFile.FullName);

                    status.Code = unchecked((uint)-1);
                    status.Message = "Invalid file: " + scrExecFile.FullName;

                    return status;
                }

            }
            finally
            {
                status.Code = scrEdit.ScriptGetLastError();
                status.Message = eStat;
            }

            return status;
        }
        /// <summary>
        /// Executes a specified script
        /// </summary>
        /// <param name="scrCmd">String containing script commands</param>
        /// <returns>Error status of execution</returns>
        public ScrErrorReport executeScript(string scrCmd)
        {
            ScrErrorReport status = new ScrErrorReport();
            status.Code = 0;
            status.Message = "Success";

            try
            {
                firstRunInit();
                while (scrEdit.executing);
                scrEdit.LoadScriptText(scrCmd);
                scrEdit.ScriptExecute(0);
            }
            finally
            {
                status.Code = scrEdit.ScriptGetLastError();
                status.Message = eStat;
            }

            return status;
        }
        /// <summary>
        /// Puts the current script into stepped mode execution
        /// </summary>
        public void executeStepScript()
        {
            scrEngine.SetScriptStep();
        }
        /// <summary>
        /// Puts the current script into free running mode execution
        /// </summary>
        public void executeRunScript()
        {
            scrEngine.SetScriptRun();
        }
        /// <summary>
        /// Terminates (gracefully) the current script execution if any
        /// </summary>
        public void terminateExecution()
        {
            scrEngine.SetScriptStep();
            scrEngine.TerminateExecution();
            scrEngine.SetScriptStep();
        }
        /// <summary>
        /// Position the script execution counter to the specified script line number
        /// </summary>
        /// <param name="execLn">Script line number</param>
        public void setExecLineTo(int execLn)
        {
            if (scrEdit.executing)
                scrEngine.SetExecToLine(execLn);
            else
                runFromLine = execLn;
        }

        #endregion

        #region Auxiliaries

        /// <summary>
        /// Returns the number of the command line that is currently being executed or -1 script is not running
        /// </summary>
        /// <returns>Current line number</returns>
        public int getExecLineNum()
        {
            return scrEngine.GetCrntExecLine();
        }
        /// <summary>
        /// Returns the currently executed command lines
        /// </summary>
        /// <returns>String collection of the command lines</returns>
        public string[] getScriptLine()
        {
            return scrEngine.GetActiveCmdLines();
        }
        /// <summary>
        /// Returns the bytestream of a selected structure
        /// </summary>
        /// <param name="compName">Component containing structure</param>
        /// <param name="structName">Structure name</param>
        /// <returns>Structure bytestream</returns>
        public byte[] getStruct(string compName, string structName)
        {
            return scrEngine.GetStruct(compName, structName);
        }
        /// <summary>
        /// Returns the bytestream of a selected structure's field
        /// </summary>
        /// <param name="compName">Component containing structure</param>
        /// <param name="structName">Structure name</param>
        /// <param name="fieldName">Field name</param>
        /// <returns>Field bytestream</returns>
        public byte[] getStructField(string compName, string structName, string fieldName)
        {
            return scrEngine.GetStructField(compName, structName, fieldName);
        }

        #endregion

        #endregion
    }
}
